<template>
  <div class="z-calendar-month">
    <div class="z-calendar-month__header">
      <div v-for="day in weekDays" :key="day" class="item">
        {{ day }}
      </div>
    </div>
    <div class="z-calendar-month__body">
      <div
        v-for="(row, index) in rows"
        :key="index"
        class="z-calendar-month__cell"
        :class="row.type"
      >
        <div class="z-calendar-month__data">
          <div class="day">
            {{ row.days }}
          </div>
          <el-link
            type="primary"
            :underline="false"
            v-if="row.count > 0"
            @click="pickFormateDate(row)"
            >共{{ row.count }}节课<i class="el-icon-arrow-right"></i
          ></el-link>
        </div>
        <div class="z-calendar-month__crad" v-for="item in row.list.slice(0, 1)" :key="item.sec_id">
          <div class="time">
            {{ item.start_time | parseTime('{h}:{i}') }}-{{ item.end_time | parseTime('{h}:{i}') }}
          </div>
          <div class="title">{{ item.course_title }}</div>
        </div>
      </div>
    </div>

    <el-drawer title="课表详情" :visible.sync="drawer" :size="450">
      <div class="z-calendar-drawer__header">
        <div class="date">{{ details.timestamp | parseTime('{y}年{m}月{d}日') }}</div>
        <div class="num">共{{ details.count }}节课</div>
      </div>
      <div class="z-calendar-drawer__body">
        <div
          class="z-calendar-drawer__crad"
          v-for="(item, index) in details.list"
          :key="index"
          :class="[{ start: item.live_status == 999, end: item.live_status == 992 }]"
          @click="pickLive(item)"
        >
          <div class="time">
            {{ item.start_time | parseTime('{h}:{i}') }}-{{ item.end_time | parseTime('{h}:{i}') }}
          </div>
          <div class="title">{{ item.course_title }}</div>
          <div class="salutation">{{ item.sec_title }}</div>
          <div class="name">{{ item.teacher_name }}</div>
          <div class="status" v-if="item.live_status == 999 || item.live_status == 992">
            {{ item.live_status == 992 ? '已结束' : '直播中' }}
          </div>
        </div>
      </div>
    </el-drawer>
  </div>
</template>

<script>
import { parseTime } from '@/utils/filters.js'
import { mapState, mapGetters } from 'vuex'
import {
  range,
  getLastDayOfMonth,
  getFirstDayOfMonth,
  getPrevMonthLastDays,
  getMonthDays
} from './date-util'
import Base64 from '@/utils/base64.js'
const validTypes = ['prev', 'today', 'next']
const getWeekDaysData = (arr1, arr2) => {
  return arr1.reduce((pre, cur) => {
    const target = pre.find(e => e.date === cur.date)
    if (target) {
      Object.assign(target, cur)
    } else {
      pre.push(cur)
    }
    return pre
  }, arr2)
}
export default {
  props: {
    value: [Date, String, Number],
    title: String,
    teacher: String
  },
  computed: {
    ...mapState({
      userInfo: state => state.user.info,
      token: state => state.user.token
    }),
    ...mapGetters({
      globThemeColor: 'projectSetting/getGlobThemeColor'
    }),
    prevMonthDatePrefix() {
      const temp = new Date(this.date.getTime())
      temp.setDate(0)
      return parseTime(temp, '{y}-{m}')
    },
    curMonthDatePrefix() {
      return parseTime(this.date, '{y}-{m}')
    },
    nextMonthDatePrefix() {
      const temp = new Date(this.date.getFullYear(), this.date.getMonth() + 1, 1)
      return parseTime(temp, '{y}-{m}')
    },
    formatedDate() {
      return parseTime(this.date, '{y}-{m}-{d}')
    },
    formatedToday() {
      return parseTime(this.now, '{y}-{m}-{d}')
    },
    realSelectedDay: {
      get() {
        return this.formatedDate
      },
      set(val) {
        const date = new Date(val)
        this.$emit('input', date)
      }
    },
    date() {
      return this.toDate(this.value)
    },
    rows() {
      let days = []
      const date = this.date
      let firstDay = getFirstDayOfMonth(date)
      firstDay = firstDay === 0 ? 7 : firstDay
      const firstDayOfWeek = 7
      const offset = (7 + firstDay - firstDayOfWeek) % 7
      const prevMonthDays = getPrevMonthLastDays(date, offset).map(day => ({
        days: day,
        type: 'prev',
        date: this.getFormateDate(day, 'prev'),
        count: 0,
        list: []
      }))
      const currentMonthDays = getMonthDays(date).map(day => ({
        days: day,
        type: 'current',
        date: this.getFormateDate(day, 'current'),
        count: 0,
        list: []
      }))
      days = [...prevMonthDays, ...currentMonthDays]
      let lastDay = getLastDayOfMonth(date)
      lastDay = 7 - lastDay - 1
      const nextMonthDays = range(lastDay).map((_, index) => ({
        days: index + 1,
        type: 'next',
        date: this.getFormateDate(index + 1, 'next'),
        count: 0,
        list: []
      }))
      days = days.concat(nextMonthDays)
      days = getWeekDaysData(this.list, days)
      return days
    },
    weekDays() {
      return ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
    }
  },
  data() {
    return {
      now: new Date(),
      list: [],
      drawer: false,
      details: {
        count: 0,
        list: [],
        timestamp: ''
      }
    }
  },
  mounted() {
    this.getData(this.curMonthDatePrefix)
  },
  methods: {
    getData(date) {
      this.list = []
      this.$api.getCourseSchedulePeriod(
        {
          startdate: this.getStartDateOfWeek(date),
          enddate: this.getEndDateOfWeek(date),
          title: this.title,
          teacher: this.teacher,
          identity: 'student'
        },
        res => {
          const { data } = res
          this.list = data
          this.list.map(item => (item.date = parseTime(item.timestamp, '{y}-{m}-{d}')))
          let sum = this.list.reduce((pre, cur) => {
            return pre + cur.count
          }, 0)
          this.$emit('number', sum)
        }
      )
    },
    pickDay(day) {
      this.realSelectedDay = day
      this.getData(day)
    },
    selectDate(type) {
      if (validTypes.indexOf(type) === -1) {
        throw new Error(`invalid type ${type}`)
      }
      let day = ''
      if (type === 'prev') {
        day = `${this.prevMonthDatePrefix}`
      } else if (type === 'next') {
        day = `${this.nextMonthDatePrefix}`
      } else {
        day = this.formatedToday
      }
      if (day === this.formatedDate) return
      this.pickDay(day)
    },
    toDate(val) {
      if (!val) {
        throw new Error('invalid val')
      }
      return val instanceof Date ? val : new Date(val)
    },
    getFormateDate(day, type) {
      if (!day || ['prev', 'current', 'next'].indexOf(type) === -1) {
        throw new Error('invalid day or type')
      }
      let prefix = this.curMonthDatePrefix
      if (type === 'prev') {
        prefix = this.prevMonthDatePrefix
      } else if (type === 'next') {
        prefix = this.nextMonthDatePrefix
      }
      day = `00${day}`.slice(-2)
      return `${prefix}-${day}`
    },
    pickFormateDate(data) {
      this.details = data
      this.drawer = true
    },
    onSearch() {
      this.getData(this.curMonthDatePrefix)
    },
    /**
     * 获取开始日期
     * @param {string} value Date string
     * @returns {string} 时间戳
     */
    getStartDateOfWeek(value) {
      const date = this.toDate(value)
      let firstDay = getFirstDayOfMonth(date)
      const offset = 7 - firstDay - 7 + 1
      if (offset > 0) {
        date.setDate(1)
      } else {
        date.setDate(offset)
      }
      date.setHours(0, 0, 0, 0)
      return parseTime(date, '{y}-{m}-{d}')
    },
    /**
     * 获取结束日期
     * @param {string} value Date string
     * @returns {string} 时间戳
     */
    getEndDateOfWeek(value) {
      const date = this.toDate(value)
      const temp = new Date(date.getFullYear(), date.getMonth() + 1, 0)
      let lastDay = getLastDayOfMonth(temp)
      lastDay = 7 - lastDay - 1
      if (lastDay > 0) {
        let time = new Date(date.getFullYear(), date.getMonth() + 1, lastDay)
        return parseTime(time, '{y}-{m}-{d}')
      }
      return parseTime(temp, '{y}-{m}-{d}')
    },
    pickLive(item) {
      let liveItem = item.sec_live
      let user = this.userInfo
      let token = this.token
      if (item.live_status === 957) {
        this.$message.info('直播未开始')
      } else if (item.live_status === 999) {
        if (this.$util.isEmpty(liveItem)) {
          console.log('live没数据')
          return
        }
        this.$store.commit('course/setCurrentPlayItem', {
          section_live: liveItem
        })
        if (liveItem.live_type === 2) {
          // 大班课
          this.$router.push({
            name: 'cc-big-class'
          })
        } else if (liveItem.live_type === 3) {
          // 小班课
          let params = {
            userid: liveItem.cc_userid,
            roomid: liveItem.cc_room_id,
            password: liveItem.authtype === 0 ? `${token.ak}:${token.sk}` : '',
            username: user.nick_name,
            autoLogin: true,
            role: 'talker',
            template: 32
          }
          const url = `https://class.csslcloud.net/hdclass/#/talker?${this.params(params)}`
          this.$router.push({
            name: 'cc-live',
            query: {
              view: Base64.encode(url)
            }
          })
        }
      } else if (item.live_status === 992) {
        if (this.$util.isEmpty(liveItem)) {
          this.$message.info('直播无回放')
          return
        }
        this.$store.commit('course/setCurrentPlayItem', {
          section_live: liveItem
        })
        if (liveItem.live_type === 2) {
          // 大班课
          if (this.$util.isEmpty(liveItem.cc_replay_id)) {
            this.$message.info('直播无回放')
          } else {
            this.$router.push({
              name: 'cc-replay-big'
            })
          }
        } else if (liveItem.live_type === 3) {
          // 小班课
          if (this.$util.isEmpty(liveItem.cc_replay_url)) {
            this.$message.info('直播无回放')
          } else {
            let params = {
              viewertoken: liveItem.authtype === 0 ? `${token.ak}:${token.sk}` : '',
              viewername: user.nick_name,
              autoLogin: true
            }
            let url = `${liveItem.cc_replay_url}&viewertoken=${params.viewertoken}&viewername=${params.viewername}&autoLogin=${params.autoLogin}`
            this.$router.push({
              name: 'cc-live',
              query: {
                view: Base64.encode(url)
              }
            })
          }
        }
      }
    },
    params(obj) {
      let result = ''
      let item
      for (item in obj) {
        if (obj[item] && String(obj[item])) {
          result += `&${item}=${obj[item]}`
        }
      }
      if (result) {
        result = result.slice(1)
      }
      return result
    }
  }
}
</script>

<style lang="scss" scoped>
::v-deep .el-calendar {
  .el-calendar__body {
    padding: 0 0 35px;
  }
  .el-calendar__header,
  .el-calendar-table thead {
    display: none;
  }
  .el-calendar-table td.is-selected {
    background-color: #ffffff;
  }
  .el-calendar-table .el-calendar-day {
    padding: 0;
    height: 120px;
  }
  .el-calendar-table td.is-today {
    color: $text-color-import;
  }
  .el-calendar-table td.next,
  .el-calendar-table td.prev {
    color: $text-color-auxiliary;
  }
}
.z-calendar-month__header {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  .item {
    height: 60px;
    font-size: 14px;
    font-weight: 500;
    color: #303133;
    line-height: 60px;
    text-align: center;
    background: #f6f7fb;
    border: 1px solid #ebeef5;
    border-left: 0;
  }
  .item:nth-child(1) {
    border-left: 1px solid #ebeef5;
  }
}
.z-calendar-month__body {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  .z-calendar-month__cell {
    height: 89px;
    min-width: 0;
    padding: 20px 10px 12px;
    line-height: 1;
    border-bottom: 1px solid #ebeef5;
    border-left: 1px solid #ebeef5;
  }
  .z-calendar-month__cell:nth-child(7n) {
    border-right: 1px solid #ebeef5;
  }
  .z-calendar-month__data {
    display: flex;
    align-items: center;
    justify-content: space-between;
    .day {
      font-size: 16px;
      font-weight: 500;
      color: $text-color-import;
    }
    .el-link {
      font-size: 12px;
    }
  }
  .z-calendar-month__crad {
    margin-top: 17px;
    padding: 10px 9px;
    background: #f6f7fb;
    border-radius: 4px;
    .time {
      font-size: 12px;
      font-weight: 400;
      color: $text-color-import;
    }
    .title {
      margin-top: 10px;
      font-size: 13px;
      font-weight: 400;
      color: $text-color-import;
      @include ellipsis;
    }
  }
  .prev .z-calendar-month__data .day,
  .next .z-calendar-month__data .day {
    color: $text-color-auxiliary;
  }
}

.z-calendar-drawer__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 20px;
  .date {
    font-size: 15px;
    font-weight: 500;
    color: $text-color-import;
  }
  .num {
    font-size: 14px;
    font-weight: 400;
    color: $text-color-auxiliary;
  }
}
.z-calendar-drawer__body {
  padding: 0 20px;
  .z-calendar-drawer__crad {
    padding: 20px 10px;
    background: #f6f7fb;
    border-radius: 4px;
    line-height: 1;
    position: relative;
    cursor: pointer;
    transition: all 0.2s;
    box-sizing: border-box;
    margin-top: 20px;
    .time {
      font-size: 14px;
      font-weight: 400;
      color: $text-color-import;
    }
    .title {
      margin-top: 15px;
      font-size: 14px;
      font-weight: 500;
      color: $text-color-import;
      @include ellipsis;
    }
    .salutation {
      margin-top: 5px;
      font-size: 12px;
      font-weight: 400;
      color: $text-color-auxiliary;
      @include ellipsis;
    }
    .name {
      margin-top: 15px;
      font-size: 12px;
      font-weight: 400;
      color: $text-color-auxiliary;
      @include ellipsis;
    }
    .status {
      position: absolute;
      right: 0;
      top: 0;
      padding: 3px 2px;
      font-size: 12px;
      font-weight: 400;
      color: #ffffff;
      border-radius: 0px 4px 0px 4px;
    }
    &.start {
      .status {
        @include edu-color-primary(background-color);
      }
    }
    &.end {
      .time,
      .title {
        color: $text-color-auxiliary;
      }
      .status {
        background: #b7bac1;
      }
    }
    &:hover {
      background: #f0f1f6;
    }
  }
}
</style>
